/* spiparser.mly */
/* Spi Calculus parser */
%{
open Printf
let parse_error s = (* Called by the parser function on error *)
  print_endline s;
  flush stdout;;
%}
%token <string> ID
%token <char> CHAR
%token NIL OK
%token BEGIN END BANG PAR OUT IN NEW DECRYPT SPLIT MATCH
%token CHAN UN KEY TOK TPAIR UNKNOWN
%token EMPTY PAIR COMMA LPAREN RPAREN LBRACE RBRACE COLON SCOLON AS

%start process
%type <Spitree.proc> process
%type <Spitree.typ> msgtype
%type <Spitree.reso> resource
%type <Spitree.msg> message

%%
process:    NIL  { Spitree.PNil }
	  | OUT LPAREN message COMMA message RPAREN  { Spitree.Out($3, $5) }
	  | IN LPAREN message COMMA ID RPAREN SCOLON process  { Spitree.In($3, $5, $8) }
	  | BANG IN LPAREN message COMMA ID RPAREN SCOLON process  { Spitree.InRepl($4, $6, $9) }
	  | NEW ID COLON msgtype SCOLON process  { Spitree.Nu($2, $4, $6) }
	  | LPAREN process PAR process RPAREN  { Spitree.PPara($2, $4) }
	  | BEGIN ID LPAREN message RPAREN  { Spitree.Begin($2, $4) }
	  | END ID LPAREN message RPAREN  { Spitree.End($2, $4) }
	  | DECRYPT message AS LBRACE ID COLON msgtype RBRACE message SCOLON process  { Spitree.Decrypt($2, $5, $7, $9, $11) }
	  | SPLIT message AS LPAREN ID COLON msgtype COMMA ID COLON msgtype RPAREN SCOLON process  { Spitree.Split($2, $5, $7, $9, $11, $14) }
	  | MATCH message COLON msgtype AS LPAREN message COMMA ID COLON msgtype RPAREN SCOLON process  { Spitree.Match($2, $4, $7, $9, $11, $14) }
;
msgtype:    UN  { Spitree.Un }
	  | UNKNOWN  { Spitree.Unknown }
	  | KEY LPAREN msgtype RPAREN  { Spitree.Key($3) }
	  | TPAIR LPAREN ID COLON msgtype COMMA msgtype RPAREN  { Spitree.TPair($3, $5, $7) }
	  | TOK LPAREN resource RPAREN  { Spitree.TOk($3) }
	  | CHAN LPAREN msgtype RPAREN  { Spitree.Ch($3) }
;
resource:   EMPTY  { Spitree.Empty }
	  | LPAREN resource COMMA resource RPAREN  { Spitree.RPair($2, $4) }
	  | ID LPAREN message RPAREN  { Spitree.Reso($1, $3) }
;
message:    OK  { Spitree.Ok }
	  | LBRACE message RBRACE message  { Spitree.Encr($2, $4) }
	  | PAIR LPAREN message COMMA message RPAREN  { Spitree.MPair($3, $5) }
	  | ID  { Spitree.Name($1) }
;
%%
